import shutil
import tkinter as tk
import tkinter.ttk
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter.messagebox import *
import xlwings as xw
import os
import os.path
import glob
import time
import fnmatch
import sys
# from pptx import Presentation
# from docx import Document
import re
import subprocess
import shutil


startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

# 调整为SW_HIDE,表示创建的进程窗口在显示时不会激活
startupinfo.wShowWindow = subprocess.SW_HIDE

# 取得路径
def app_path():
    if hasattr(sys, 'frozen'):  # 可执行文件走这里
        return os.path.abspath(sys.executable)
    return os.path.abspath(__file__)  # 源码走这里

# 界面作成
window = tk.Tk()
window.title("Check jira")
window.geometry("700x350+600+400") 

# 创建 PanedWindow
paned_window = ttk.PanedWindow(window, orient=tk.HORIZONTAL)
paned_window.pack(fill=tk.BOTH, expand=True)
# 创建左侧的 Frame 用于放置按钮
left_frame = ttk.Frame(paned_window, width=150)
paned_window.add(left_frame, weight=1)
# 创建右侧的 Frame 用于显示具体内容
right_frame = ttk.Frame(paned_window)
paned_window.add(right_frame, weight=5)
# -------------------------------------------------------------------------------------page_1-------------------------------------------------------------------------------------
# 界面参数
page_1 = ttk.Frame(right_frame)

def on_entry_pi_in(event):
    if PI_entry.get() == "eg:PI26":
        PI_entry.delete(0, tk.END)  # 清空内容
        PI_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_pi_out(event):
    if PI_entry.get() == "":
        PI_entry.insert(0, "eg:PI26")  # 插入提示字符
        PI_entry.config(fg="grey")  # 设置文本颜色为灰色
# PI
PI_label = tk.Label(page_1, width=10, text="PI")
PI_label.place(x=50, y=35, anchor="w")
PI_entry = tk.Entry(page_1, width=10, fg="grey")
PI_entry.insert(0, "eg:PI26")  # 设置初始提示字符
PI_entry.place(x=100, y=35, anchor="w")
# 绑定事件
PI_entry.bind("<FocusIn>", on_entry_pi_in)  # 获取焦点时触发
PI_entry.bind("<FocusOut>", on_entry_pi_out)  # 失去焦点时触发

def on_entry_ed_in(event):
    if ED_entry.get() == "eg:1":
        ED_entry.delete(0, tk.END)  # 清空内容
        ED_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_ed_out(event):
    if ED_entry.get() == "":
        ED_entry.insert(0, "eg:1")  # 插入提示字符
        ED_entry.config(fg="grey")  # 设置文本颜色为灰色
# ED
ED_label = tk.Label(page_1, width=10, text="ED")
ED_label.place(x=150, y=35, anchor="w")
ED_entry = tk.Entry(page_1, width=10, fg="grey")
ED_entry.insert(0, "eg:1")  # 设置初始提示字符
ED_entry.place(x=200, y=35, anchor="w")
# 绑定事件
ED_entry.bind("<FocusIn>", on_entry_ed_in)  # 获取焦点时触发
ED_entry.bind("<FocusOut>", on_entry_ed_out)  # 失去焦点时触发

def on_entry_focus_in(event):
    if SQ_entry.get() == "eg:Sq22":
        SQ_entry.delete(0, tk.END)  # 清空内容
        SQ_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_focus_out(event):
    if SQ_entry.get() == "":
        SQ_entry.insert(0, "eg:Sq22")  # 插入提示字符
        SQ_entry.config(fg="grey")  # 设置文本颜色为灰色
# SQ
SQ_label = tk.Label(page_1, width=10, text="SQ")
SQ_label.place(x=250, y=35, anchor="w")
SQ_entry = tk.Entry(page_1, width=10, fg="grey")
SQ_entry.insert(0, "eg:Sq22")  # 设置初始提示字符
SQ_entry.place(x=300, y=35, anchor="w")
# 绑定事件
SQ_entry.bind("<FocusIn>", on_entry_focus_in)  # 获取焦点时触发
SQ_entry.bind("<FocusOut>", on_entry_focus_out)  # 失去焦点时触发

# 文件路径
def importfile_file_select_1():
    file_path = filedialog.askopenfilename()
    import_1.config(text=file_path)
import_1 = tk.Message(page_1, width=300, text="")
import_1.place(x=20, y=70, anchor="w")
import_botton_1 = tk.Button(page_1, text="import csv", width=10, command=importfile_file_select_1)
import_botton_1.place(x=350, y=50)

def on_entry_edsh_in(event):
    if edsh_entry.get() == "ED式样sheet名":
        edsh_entry.delete(0, tk.END)  # 清空内容
        edsh_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_edsh_out(event):
    if edsh_entry.get() == "":
        edsh_entry.insert(0, "ED式样sheet名")  # 插入提示字符
        edsh_entry.config(fg="grey")  # 设置文本颜色为灰色
# PI
# edsh_label = tk.Label(page_1, width=10, text="ED式样sheet")
# edsh_label.place(x=50, y=35, anchor="w")
edsh_entry = tk.Entry(page_1, width=20, fg="grey")
edsh_entry.insert(0, "ED式样sheet名")  # 设置初始提示字符
edsh_entry.place(x=20, y=100, anchor="w")
# 绑定事件
edsh_entry.bind("<FocusIn>", on_entry_edsh_in)  # 获取焦点时触发
edsh_entry.bind("<FocusOut>", on_entry_edsh_out)  # 失去焦点时触发

def on_entry_ed_gui_in(event):
    if ed_gui_entry.get() == "GUI sheet名":
        ed_gui_entry.delete(0, tk.END)  # 清空内容
        ed_gui_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_ed_gui_out(event):
    if ed_gui_entry.get() == "":
        ed_gui_entry.insert(0, "GUI sheet名")  # 插入提示字符
        ed_gui_entry.config(fg="grey")  # 设置文本颜色为灰色
# ED
# ED_label = tk.Label(page_1, width=10, text="ED")
# ED_label.place(x=150, y=35, anchor="w")
ed_gui_entry = tk.Entry(page_1, width=20, fg="grey")
ed_gui_entry.insert(0, "GUI sheet名")  # 设置初始提示字符
ed_gui_entry.place(x=150, y=100, anchor="w")
# 绑定事件
ed_gui_entry.bind("<FocusIn>", on_entry_ed_gui_in)  # 获取焦点时触发
ed_gui_entry.bind("<FocusOut>", on_entry_ed_gui_out)  # 失去焦点时触发

def on_entry_ed_fun_in(event):
    if ed_fun_entry.get() == "Function sheet名":
        ed_fun_entry.delete(0, tk.END)  # 清空内容
        ed_fun_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_ed_fun_out(event):
    if ed_fun_entry.get() == "":
        ed_fun_entry.insert(0, "Function sheet名")  # 插入提示字符
        ed_fun_entry.config(fg="grey")  # 设置文本颜色为灰色
# SQ
# ed_fun_label = tk.Label(page_1, width=10, text="SQ")
# ed_fun_label.place(x=250, y=35, anchor="w")
ed_fun_entry = tk.Entry(page_1, width=20, fg="grey")
ed_fun_entry.insert(0, "Function sheet名")  # 设置初始提示字符
ed_fun_entry.place(x=280, y=100, anchor="w")
# 绑定事件
ed_fun_entry.bind("<FocusIn>", on_entry_ed_fun_in)  # 获取焦点时触发
ed_fun_entry.bind("<FocusOut>", on_entry_ed_fun_out)  # 失去焦点时触发

def requirement_file_select_1():
    file_path = filedialog.askopenfilename()
    requirement_1.config(text=file_path)
requirement_1 = tk.Message(page_1, width=300, text="")
requirement_1.place(x=20, y=135, anchor="w")
requirement_botton_1 = tk.Button(page_1, text="需求分析", width=10, command=requirement_file_select_1)
requirement_botton_1.place(x=350, y=115)

def on_entry_spec_gui_in(event):
    if spec_gui_entry.get() == "GUI sheet名":
        spec_gui_entry.delete(0, tk.END)  # 清空内容
        spec_gui_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_spec_gui_out(event):
    if spec_gui_entry.get() == "":
        spec_gui_entry.insert(0, "GUI sheet名")  # 插入提示字符
        spec_gui_entry.config(fg="grey")  # 设置文本颜色为灰色

spec_gui_entry = tk.Entry(page_1, width=20, fg="grey")
spec_gui_entry.insert(0, "GUI sheet名")  # 设置初始提示字符
spec_gui_entry.place(x=150, y=160, anchor="w")
# 绑定事件
spec_gui_entry.bind("<FocusIn>", on_entry_spec_gui_in)  # 获取焦点时触发
spec_gui_entry.bind("<FocusOut>", on_entry_spec_gui_out)  # 失去焦点时触发

def on_entry_spec_fun_in(event):
    if spec_fun_entry.get() == "Function sheet名":
        spec_fun_entry.delete(0, tk.END)  # 清空内容
        spec_fun_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_spec_fun_out(event):
    if spec_fun_entry.get() == "":
        spec_fun_entry.insert(0, "Function sheet名")  # 插入提示字符
        spec_fun_entry.config(fg="grey")  # 设置文本颜色为灰色

spec_fun_entry = tk.Entry(page_1, width=20, fg="grey")
spec_fun_entry.insert(0, "Function sheet名")  # 设置初始提示字符
spec_fun_entry.place(x=280, y=160, anchor="w")
# 绑定事件
spec_fun_entry.bind("<FocusIn>", on_entry_spec_fun_in)  # 获取焦点时触发
spec_fun_entry.bind("<FocusOut>", on_entry_spec_fun_out)  # 失去焦点时触发

def specList_file_select_1():
    file_path = filedialog.askopenfilename()
    specList_1.config(text=file_path)
specList_1 = tk.Message(page_1, width=300, text="")
specList_1.place(x=20, y=195, anchor="w")
specList_botton_1 = tk.Button(page_1, text="SpecList", width=10, command=specList_file_select_1)
specList_botton_1.place(x=350, y=175)

def epic_file_select_1():
    file_path = filedialog.askopenfilename()
    epic_1.config(text=file_path)
epic_1 = tk.Message(page_1, width=300, text="")
epic_1.place(x=20, y=240, anchor="w")
epic_botton_1 = tk.Button(page_1, text="epic csv", width=10, command=epic_file_select_1)
epic_botton_1.place(x=350, y=220)

def start_1():
    datacheck_1(import_1["text"], requirement_1["text"], specList_1["text"], epic_1["text"])
status_1 = tk.Label(page_1, width=50, text="")
status_1.place(x=30, y=270, anchor="w")
start_botton_1 = tk.Button(page_1, text="开始", width=10, command=start_1)
start_botton_1.place(x=350, y=270)

def datacheck_1(importfile, requirement, SpecList, epic):
    status_1["text"] = "......"
    page_1.update()
    time.sleep(0.05)
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except Exception as e:
        pass

    ED_value = str(ED_entry.get()).strip()
    if not ED_value.isnumeric():
        print(showwarning(title="warning", message=f"输入ED=[{ED_value}]数据不是纯数字"))
        return

    PI_value = str(PI_entry.get()).strip()
    pattern = r'^PI\d+$'
    PI_match = re.match(pattern, PI_value)
    if PI_match:
        Labels_1_value = f"{PI_value}_Preparation"
        Labels_2_value = f"{PI_value}_ED{ED_value}"
    else:
        print(showwarning(title="warning", message=f"输入PI=[{PI_value}]数据不正确"))
        return

    SQ_value = str(SQ_entry.get()).strip()
    pattern = r'^Sq\d+$'
    SQ_match = re.match(pattern, SQ_value)
    if not SQ_match:
        print(showwarning(title="warning", message=f"输入SQ=[{SQ_value}]数据不正确"))
        return

    app = xw.App(visible=False,add_book=False)

    epic_dict = {}
    try:
        if "epic" in epic:
            epic_book = app.books.open(epic, update_links=False)
            cell_keyword = epic_book.sheets(1).range("1:1").api.Find("Issue key")
            if cell_keyword:
                find_col = cell_keyword.Column
                column_letter = xw.utils.col_name(find_col)
                for no in epic_book.sheets(1).range(f"{column_letter}:{column_letter}"):
                    if str(no.value) != "None" and str(no.value) != "Issue key":
                        epic_dict[str(no.value).strip()] = str(no.offset(0,4).value).strip()
                    else:
                        if epic_dict:
                            break
            else:
                app.quit()
                print(showwarning(title="warning", message=f"[{epic}]文件中未找到[Issue key]列"))
                return
        else:
            app.quit()
            print(showwarning(title="warning", message="请选择正确的epic文件"))
            return
        epic_book.close()
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{epic}]文件失败[{e}]"))
        return

    spec_gui_value = str(spec_gui_entry.get()).strip()
    if spec_gui_value == "GUI sheet名":
        print(showwarning(title="warning", message=f"未输入SpecList文件[GUI sheet名]"))
        return
    spec_fun_value = str(spec_fun_entry.get()).strip()
    if spec_fun_value == "Function sheet名":
        print(showwarning(title="warning", message=f"未输入SpecList文件[Function sheet名]"))
        return
    SpecList_dict = {}
    try:
        if not "SpecList" in SpecList:
            app.quit()
            print(showwarning(title="warning", message="请选择正确的SpecList文件"))
            return
        SpecList_book = app.books.open(SpecList, update_links=False)
        sht_SpecList_GUI = SpecList_book.sheets(spec_gui_value)
        sht_SpecList_FUN = SpecList_book.sheets(spec_fun_value)
    
        cell_keyword = sht_SpecList_GUI.range("2:2").api.Find("Ordinary")
        Ordinary_col = cell_keyword.Column
        cell_keyword = sht_SpecList_GUI.range("2:2").api.Find("Popup")
        Popup_col = cell_keyword.Column
        cell_keyword = sht_SpecList_GUI.range("2:2").api.Find("AD")
        AD_col = cell_keyword.Column
        cell_keyword = sht_SpecList_GUI.range("2:2").api.Find("File Name of Spec")
        if cell_keyword:
            find_col = cell_keyword.Column
            column_letter = xw.utils.col_name(find_col)
            for no in sht_SpecList_GUI.range(f"{column_letter}:{column_letter}"):
                if str(no.value) != "None" and str(no.value) != "File Name of Spec":
                    Feature = []
                    if str(sht_SpecList_GUI.range((no.row, Ordinary_col)).value).strip() == "○":
                        Feature.append('Ordinary')
                    if str(sht_SpecList_GUI.range((no.row, Popup_col)).value).strip() == "○":
                        Feature.append('Popup')
                    if str(sht_SpecList_GUI.range((no.row, AD_col)).value).strip() == "○":
                        Feature.append('AD')
                    if Feature:
                        SpecList_dict[str(no.value).strip()] = Feature
                else:
                    if SpecList_dict:
                        break
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{SpecList}]文件sheet[{spec_gui_value}]中未找到[File Name of Spec]列"))
            return

        cell_keyword = sht_SpecList_FUN.range("2:2").api.Find("Ordinary")
        Ordinary_col = cell_keyword.Column
        cell_keyword = sht_SpecList_FUN.range("2:2").api.Find("Popup")
        Popup_col = cell_keyword.Column
        cell_keyword = sht_SpecList_FUN.range("2:2").api.Find("AD")
        AD_col = cell_keyword.Column
        cell_keyword = sht_SpecList_FUN.range("2:2").api.Find("File Name of Spec")
        break_flag = False
        if cell_keyword:
            find_col = cell_keyword.Column
            column_letter = xw.utils.col_name(find_col)
            for no in sht_SpecList_FUN.range(f"{column_letter}:{column_letter}"):
                if str(no.value) != "None" and str(no.value) != "File Name of Spec":
                    break_flag = True
                    Feature = []
                    if str(sht_SpecList_FUN.range((no.row, Ordinary_col)).value).strip() == "○":
                        Feature.append('Ordinary')
                    if str(sht_SpecList_FUN.range((no.row, Popup_col)).value).strip() == "○":
                        Feature.append('Popup')
                    if str(sht_SpecList_FUN.range((no.row, AD_col)).value).strip() == "○":
                        Feature.append('AD')
                    if Feature:
                        SpecList_dict[str(no.value).strip()] = Feature
                else:
                    if break_flag:
                        break
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{SpecList}]文件sheet[{spec_fun_value}]中未找到[File Name of Spec]列"))
            return
        SpecList_book.close()
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{SpecList}]文件失败[{e}]"))
        return


    edsh_value = str(edsh_entry.get()).strip()
    if edsh_value == "ED式样sheet名":
        print(showwarning(title="warning", message=f"未输入需求分析文件[ED式样sheet名]"))
        return
    ed_gui_value = str(ed_gui_entry.get()).strip()
    if ed_gui_value == "GUI sheet名":
        print(showwarning(title="warning", message=f"未输入需求分析文件[GUI sheet名]"))
        return
    ed_fun_value = str(ed_fun_entry.get()).strip()
    if ed_fun_value == "Function sheet名":
        print(showwarning(title="warning", message=f"未输入需求分析文件[Function sheet名]"))
        return
    ED_dict = {}
    ED_due_dict = {}
    try:
        if not "需求分析确认" in requirement:
            print(showwarning(title="warning", message="请选择正确的需求分析文件"))
            app.quit()
            return
        requirement_book = app.books.open(requirement, update_links=False)
        sht_ED = requirement_book.sheets(edsh_value)
        sht_GUI = requirement_book.sheets(ed_gui_value)
        sht_Function = requirement_book.sheets(ed_fun_value)
        cell_keyword = sht_ED.range("1:1").api.Find("Contents")
        if cell_keyword:
            find_col = cell_keyword.Column
            column_letter = xw.utils.col_name(find_col)
            cell_keyword = sht_ED.range("1:1").api.Find("due date")
            due_col = cell_keyword.Column
            for no in sht_ED.range(f"{column_letter}:{column_letter}"):
                if str(no.value).strip() != "None" and str(no.value).strip() != "Contents":
                    ED_due_dict[str(no.value).strip()] = str(sht_ED.range((no.row, due_col)).value).strip()
                else:
                    if ED_due_dict:
                        break
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{requirement}]文件sheet[{edsh_value}]中未找到[File Name of Spec]"))
            return
        
        cell_keyword = sht_GUI.range("2:2").api.Find("File Name of Spec")
        if cell_keyword:
            find_col = cell_keyword.Column
            column_letter = xw.utils.col_name(find_col)
            cell_keyword = sht_GUI.range("2:2").api.Find("Change Type")
            Change_col = cell_keyword.Column
            for no in sht_GUI.range(f"{column_letter}:{column_letter}"):
                no_value = str(no.value).strip()
                change_value = str(sht_GUI.range((no.row, Change_col)).value).strip()
                Contents_value = str(sht_GUI.range((no.row, 1)).value).strip()
                if no_value != "None" and no_value != "File Name of Spec":
                    name_due = {}
                    if no_value in SpecList_dict:
                        name_due["Change Type"] = change_value
                        if Contents_value in ED_due_dict:
                            name_due["due date"] = ED_due_dict[Contents_value]
                    if name_due:
                        ED_dict[no_value] = name_due
                else:
                    if ED_dict:
                        break
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{requirement}]文件sheet[{ed_gui_value}]中未找到[File Name of Spec]"))
            return
        cell_keyword = sht_Function.range("2:2").api.Find("File Name of Spec")
        break_flag = False
        if cell_keyword:
            find_col = cell_keyword.Column
            column_letter = xw.utils.col_name(find_col)
            cell_keyword = sht_Function.range("2:2").api.Find("Change Type")
            Change_col = cell_keyword.Column
            for no in sht_Function.range(f"{column_letter}:{column_letter}"):
                no_value = str(no.value).strip()
                change_value = str(sht_Function.range((no.row, Change_col)).value).strip()
                Contents_value = str(sht_Function.range((no.row, 1)).value).strip()
                if no_value != "None" and no_value != "File Name of Spec":
                    break_flag = True
                    name_due = {}
                    if no_value in SpecList_dict:
                        name_due["Change Type"] = change_value
                        if Contents_value in ED_due_dict:
                            name_due["due date"] = ED_due_dict[Contents_value]
                    if name_due:
                        ED_dict[no_value] = name_due
                else:
                    if break_flag:
                        break
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{requirement}]文件sheet[{ed_fun_value}]中未找到[File Name of Spec]"))
            return
        requirement_book.close()
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{requirement}]文件失败[{e}]"))
        return


    error_list = []
    try:
        importfile_book = app.books.open(importfile, update_links=False)
        if importfile_book.sheets(1).range("A1").value != "Issue Type":
            app.quit()
            print(showwarning(title="warning", message=f"[{importfile}]文件A1不是[Issue Type]"))
            return
        else:
            for no in importfile_book.sheets(1).range("A:A"):
                IssueType = str(no.value).strip()
                Summary = str(no.offset(0,1).value).strip()
                Feature = str(no.offset(0,2).value).strip()
                DueDate = str(no.offset(0,3).value).strip()
                EpicLink = str(no.offset(0,4).value).strip()
                Assignee = str(no.offset(0,5).value).strip()
                Reporter = str(no.offset(0,6).value).strip()
                Description = str(no.offset(0,7).value).strip()
                Priority = str(no.offset(0,8).value).strip()
                Labels_1 = str(no.offset(0,9).value).strip()
                Labels_2 = str(no.offset(0,10).value).strip()
                Labels_3 = str(no.offset(0,11).value).strip()
                SpecTender = str(no.offset(0,12).value).strip()
                AASP_Doc = str(no.offset(0,13).value).strip()
                Cluster = str(no.offset(0,14).value).strip()
                PI_1 = str(no.offset(0,15).value).strip()
                line = str(no.row).strip()
                
                if IssueType == "None":
                    break
                if IssueType != "Issue Type":
                    if IssueType != "SpecChange":
                        error_list.append(f"第[{line}]行, Issue Type 列数据不是 SpecChange")
                    if Assignee != Reporter:
                        error_list.append(f"第[{line}]行, Assignee 和 Reporter 列数据不一致")
                    if Priority != "B":
                        error_list.append(f"第[{line}]行, Priority 列数据不是 B")
                    if Labels_1 != Labels_1_value:
                        error_list.append(f"第[{line}]行, Labels_1 列数据不是[{Labels_1_value}]")
                    if Labels_2 != Labels_2_value:
                        error_list.append(f"第[{line}]行, Labels_2 列数据不是[{Labels_2_value}]")
                    if Labels_3 != "Cluster":
                        error_list.append(f"第[{line}]行, Labels_3 列数据不是 Cluster")
                    if SpecTender != SQ_value:
                        error_list.append(f"第[{line}]行, SpecTender 列数据不是[{SQ_value}]")
                    if AASP_Doc == "None":
                        error_list.append(f"第[{line}]行, AASP Doc / CS Link 列数据是 None")
                    if Cluster != "Cluster":
                        error_list.append(f"第[{line}]行, Cluster 列数据不是 Cluster")
                    if PI_1 != PI_value:
                        error_list.append(f"第[{line}]行, PI_1 列数据不是[{PI_value}]")

                    pattern = r'\[(\w+)\]\[(\w+)\]\[(\w+)\]-\[([^\]]+)\]-QNX-(\w+)$'
                    matches = re.match(pattern, Summary)
                    if matches:
                        pi_value = str(matches.group(1)).strip()
                        ed_value = str(matches.group(2)).strip()
                        sq_value = str(matches.group(3)).strip()
                        filename_value = str(matches.group(4)).strip()
                        feature_value = str(matches.group(5)).strip()
                        filename_type = False
                        if pi_value != PI_value:
                            error_list.append(f"第[{line}]行, Summary 列数据[{pi_value}]不正确")
                        if ed_value != f"Ed{ED_value}":
                            error_list.append(f"第[{line}]行, Summary 列数据[{ed_value}]不正确")
                        if sq_value != SQ_value:
                            error_list.append(f"第[{line}]行, Summary 列数据[{sq_value}]不正确")
                        if filename_value.endswith("(delete)"):
                            filename_type = True
                            filename_value = filename_value.replace("(delete)","")
                        if filename_value in SpecList_dict:
                            if feature_value not in SpecList_dict[filename_value]:
                                error_list.append(f"第[{line}]行, Summary 列数据[{feature_value}]不正确")
                            if filename_value in ED_dict:
                                if filename_type and ED_dict[filename_value]["Change Type"] != "delete":
                                    error_list.append(f"第[{line}]行, Summary 列数据[{filename_value}]文件的[Change Type]不正确的")
                                if ED_dict[filename_value]["due date"] != DueDate:
                                    error_list.append(f"第[{line}]行, due date 列数据[{DueDate}]不正确的")
                            else:
                                error_list.append(f"第[{line}]行, Summary 列数据[{filename_value}]未找到正确的[due data]和[Change Type]")
                            if EpicLink in epic_dict:
                                last_dot_index = filename_value.rfind('.')
                                file_name = filename_value[:last_dot_index]
                                if file_name not in epic_dict[EpicLink]:
                                    error_list.append(f"第[{line}]行, Epic Link(CDCFM) 列数据[{EpicLink}]不正确")
                            else:
                                error_list.append(f"第[{line}]行, Epic Link(CDCFM) 列数据[{EpicLink}]未找到有效数据")
                        else:
                            error_list.append(f"第[{line}]行, Summary 列数据[{filename_value}]未找到有效数据")
                    else:
                        error_list.append(f"第[{line}]行, Summary 列数据[{Summary}]格式不正确")
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{importfile}]文件失败[{e}]"))
        return
    
    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')
    app.quit()
    print(showinfo(title="info", message=f"SpecChange起票前csv检查[SUCCESS END] !!!"))

def time_change(time_before):
    time_after = time_before.replace(chr(0), "")
    time_after = time_after.replace("-", "/")
    time_after = time_after.replace("/0", "/")
    time_after = time_after.replace("00:00:00", "")
    time_after = time_after.replace(" ", "")
    return time_after

# -------------------------------------------------------------------------------------page_2-------------------------------------------------------------------------------------
# 界面参数
page_2 = ttk.Frame(right_frame)
# notebook.add(page_2, text="")

# 文件路径
def import_file_select_2():
    file_path = filedialog.askopenfilename()
    import_2.config(text=file_path)
import_2 = tk.Message(page_2, width=300, text="")
import_2.place(x=20, y=50, anchor="w")
import_botton_2 = tk.Button(page_2, text="import csv", width=10, command=import_file_select_2)
import_botton_2.place(x=350, y=35)

def download_file_select_2():
    file_path = filedialog.askopenfilename()
    download_2.config(text=file_path)
download_2 = tk.Message(page_2, width=300, text="")
download_2.place(x=20, y=110, anchor="w")
download_botton_1 = tk.Button(page_2, text="download csv", width=10, command=download_file_select_2)
download_botton_1.place(x=350, y=95)

def start_2():
    datacheck_2(import_2["text"], download_2["text"])
status_2 = tk.Label(page_2, width=50, text="")
status_2.place(x=30, y=170, anchor="w")
start_botton_2 = tk.Button(page_2, text="开始", width=10, command=start_2)
start_botton_2.place(x=350, y=155)

def datacheck_2(import_file, download_file):
    status_2["text"] = "......"
    page_2.update()
    time.sleep(0.05)
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except:
        pass

    app = xw.App(visible=False,add_book=False)
    import_dict = {}
    try:
        import_book = app.books.open(import_file, update_links=False)
        cell_keyword = import_book.sheets(1).range("1:1").api.Find("Summary")
        if cell_keyword:
            find_col = cell_keyword.Column
            # 获取所有数据
            import_data = import_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in import_data:
                if row_num != 1:
                    row_value = {}
                    for index, item in enumerate(row):
                        tmp_key = str(import_data[0][index]).strip()
                        item = str(item).strip()
                        if tmp_key in row_value:
                            row_value[tmp_key] = f"{row_value[tmp_key]},{item}"
                        else:
                            row_value[tmp_key] = item
                    row_value["row_num"] = row_num
                    import_dict[str(row[find_col-1]).strip()] = row_value
                row_num += 1
            # print(import_dict)
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{importfile}]文件sheet1中第一行未找到[Summary]列"))
            return
        import_book.close()
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{importfile}]文件失败[{e}]"))
        return

    download_dict = {}
    try:
        download_book = app.books.open(download_file, update_links=False)
        cell_keyword = download_book.sheets(1).range("1:1").api.Find("Summary")
        if cell_keyword:
            find_col = cell_keyword.Column
            # 获取所有数据
            download_data = download_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in download_data:
                if row_num != 1:
                    row_value = {}
                    for index, item in enumerate(row):
                        tmp_key = str(download_data[0][index]).strip()
                        item = str(item).strip()
                        if tmp_key in row_value:
                            row_value[tmp_key] = f"{row_value[tmp_key]},{item}"
                        else:
                            row_value[tmp_key] = item
                    row_value["row_num"] = row_num
                    download_dict[str(row[find_col-1]).strip()] = row_value
                row_num += 1
            # print(download_dict)
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{download_file}]文件sheet1中第一行未找到[Summary]列"))
            return
        download_book.close()
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{download_file}]文件失败[{e}]"))
        return

    tital_dict = {
        'Issue Type':'Issue Type',
        'Summary':'Summary',
        'Feature':'Custom field (Feature)',
        'due data':'Due Date',
        'Epic Link(CDCFM)':'Custom field (Epic Link)',
        'Assignee':'Assignee',
        'Reporter':'Reporter',
        'Description':'Custom field (Description)',
        'Priority':'Priority',
        'Labels':'Labels',
        'SpecTender':'Custom field (SpecTender)',
        'AASP Doc / CS Link':'Custom field (AASP Doc / CS Link)',
        'Cluster/IVIRequired':'Custom field (Cluster/IVI)',
        'PI':'Custom field (PI)'
        }
    error_list = []
    # 遍历字典列表
    for key,values in import_dict.items():
        line = values["row_num"]
        if key in download_dict:
            for k,val in values.items():
                if k in tital_dict:
                    dval = download_dict[key][tital_dict[k]]
                    if val != dval:
                        if k == "Labels":
                            val_list = val.split(",")
                            for v in val_list:
                                if v not in dval:
                                    error_list.append(f"文件[{import_file}]第[{line}]行数据[{k}:{val}]与文件[{download_file}]中第[{download_dict[key]["row_num"]}]行数据[{tital_dict[k]}:{dval}]不一致")
                        else:
                            error_list.append(f"文件[{import_file}]第[{line}]行数据[{k}:{val}]与文件[{download_file}]中第[{download_dict[key]["row_num"]}]行数据[{tital_dict[k]}:{dval}]不一致")
        else:
            error_list.append(f"文件[{import_file}]第[{line}]行数据[{key}]在文件[{download_file}]中未找到匹配数据 !!!")

    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')

    app.quit()
    print(showinfo(title="info", message=f"SpecChange期票后票的检查[SUCCESS END] !!!"))

# -------------------------------------------------------------------------------------page_3-------------------------------------------------------------------------------------
# 界面参数
page_3 = ttk.Frame(right_frame)
# notebook.add(page_3, text="")

# 文件路径
def download_file_select_3():
    file_path = filedialog.askopenfilename()
    download_3.config(text=file_path)
download_3 = tk.Message(page_3, width=300, text="")
download_3.place(x=20, y=50, anchor="w")
download_botton_3 = tk.Button(page_3, text="SpecChange csv", width=15, command=download_file_select_3)
download_botton_3.place(x=350, y=35)

# SVN路径
SVNpath_3 = tk.Entry(page_3, width=50)
SVNpath_3.place(x=25, y=100, anchor="w")
SVNtext_3 = tk.Label(page_3, width=15, text="SpecDelta SVN Url")
SVNtext_3.place(x=335, y=100, anchor="w")
# SVN文件本地存储路径
def on_entry_local_in(event):
    if SVNpath_3_1.get() == "本地存储目录中不能含有中文字符！！！":
        SVNpath_3_1.delete(0, tk.END)  # 清空内容
        SVNpath_3_1.config(fg="black")  # 设置文本颜色为黑色

def on_entry_local_out(event):
    if SVNpath_3_1.get() == "":
        SVNpath_3_1.insert(0, "本地存储目录中不能含有中文字符！！！")  # 插入提示字符
        SVNpath_3_1.config(fg="grey")  # 设置文本颜色为灰色
# 绑定事件
SVNpath_3_1 = tk.Entry(page_3, width=50, fg="grey")
SVNpath_3_1.insert(0, "本地存储目录中不能含有中文字符！！！")
SVNpath_3_1.place(x=25, y=130, anchor="w")
SVNpath_3_1.bind("<FocusIn>", on_entry_local_in)  # 获取焦点时触发
SVNpath_3_1.bind("<FocusOut>", on_entry_local_out)  # 失去焦点时触发

SVNtext_3_1 = tk.Label(page_3, width=15, text="SpecDelta本地路径")
SVNtext_3_1.place(x=335, y=130, anchor="w")

def start_3(type):
    datacheck_3(download_3["text"], SVNpath_3.get(), SVNpath_3_1.get(), type)
status_3 = tk.Label(page_3, width=50, text="")
status_3.place(x=30, y=160, anchor="w")
start_botton_3 = tk.Button(page_3, text="第一阶段检查", width=10, command=lambda: start_3(1))
start_botton_3.place(x=100, y=200)

start_botton_3_2 = tk.Button(page_3, text="第二阶段检查", width=10, command=lambda: start_3(2))
start_botton_3_2.place(x=200, y=200)


def datacheck_3(download_file, svn_url, local_path, type):
    status_3["text"] = "......"
    page_3.update()
    time.sleep(0.05)
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except:
        pass

    local_dir = f"{local_path}\\Spec-file"
    if os.path.exists(local_dir):
        shutil.rmtree(local_dir)
    # os.makedirs(local_dir)
    # 构建SVN命令
    command = ['svn', 'export', svn_url, local_dir]
    try:
        # subprocess.run(command, check=True, startupinfo=startupinfo)
        result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        print("SVN export 成功！")
        print("输出:", result.stdout)
    except subprocess.CalledProcessError as e:
        print(showwarning(title="warning", message=f"SVN export 失败！错误信息:[{e.stderr}]"))
    except FileNotFoundError:
        print(showwarning(title="warning", message="未找到 'svn' 命令，请确保已安装 SVN 客户端并配置了环境变量。"))

    app = xw.App(visible=False,add_book=False)
    # 正则表达式匹配版本号，假设版本号格式为 v1.2
    ScreenID_message = [
        'There is no need to correspond to changes in the specifications document; therefore, there is no associated screen ID.',
        'No associated screen ID for the specification change.',
        'The changes of the specification don\'t need to be handled, so there is no associated screen ID.',
        'CAN signal time out function, no display content related.'
        ]
    error_list = []
    version_pattern = re.compile(r'v(\d+\.\d+)')
    AD_version = None
    Ordinary_version = None
    Popup_version = None
    # 遍历目录中的所有文件
    version_file = {}
    for root, dirs, files in os.walk(local_dir):
        for filename in files:
            match = version_pattern.search(filename)
            if match:
                version = match.group(1)
                # 将版本号字符串转换为元组，以便比较
                version_tuple = tuple(map(int, version.split('.')))
                if filename.startswith("AD_SpecDeltaAnalysis"):
                    if AD_version is None or version_tuple > AD_version:
                        AD_version = version_tuple
                        version_file["AD"] = os.path.join(root, filename)
                if filename.startswith("Ordinary_SpecDeltaAnalysis"):
                    if Ordinary_version is None or version_tuple > Ordinary_version:
                        Ordinary_version = version_tuple
                        version_file["Ordinary"] = os.path.join(root, filename)
                if filename.startswith("Popup_SpecDeltaAnalysis"):
                    if Popup_version is None or version_tuple > Popup_version:
                        Popup_version = version_tuple
                        version_file["Popup"] = os.path.join(root, filename)
    print(f"version_file={version_file}")
    spec_dict = {}
    tmp_sheet = svn_url.split('/')[-1]
    sheet_suffix = tmp_sheet.split('-')[-1]
    for key,value in version_file.items():
        try:
            print(f"start {value}")
            key_book = app.books.open(value, update_links=False)
            for sheet in key_book.sheets:
                if f"_Function_{sheet_suffix}" in sheet.name:
                    cell_keyword = key_book.sheets(sheet.name).range("2:2").api.Find("Function No.")
                elif f"_GUI_{sheet_suffix}" in sheet.name or f"Animation List_{sheet_suffix}" in sheet.name:
                    cell_keyword = key_book.sheets(sheet.name).range("2:2").api.Find("Sheet Name")
                else:
                    print(f"sheet.name={sheet.name} continue")
                    continue

                if cell_keyword:
                    find_col = cell_keyword.Column
                    # 获取所有数据
                    sheet_data = key_book.sheets(sheet.name).used_range.value
                    # 打印数据
                    row_num = 1
                    for row in sheet_data:
                        if row_num > 2:
                            row_value = {}
                            if set(row) == {None}:
                                continue
                            for index, item in enumerate(row):
                                if index != 0:
                                    col_name = str(sheet_data[1][index]).strip()
                                    item = str(item).strip()
                                    if col_name == "OPL":
                                        if item != "No Need" and item != "None":
                                            item = item.replace("No Need\n","")
                                    elif str(col_name).startswith("SWE"):
                                        if '\n' in item and item != "None":
                                            item = str(item).split("\n").pop()
                                        if item == "Yes":
                                            item = "Need"
                                        else:
                                            item = "No Need"
                                    elif col_name == "ScreenID":
                                        if '\n' in item and item != "None":
                                            item = str(item).replace("\r","")
                                            item = str(item).replace("\n",",")
                                    row_value[col_name] = item
                            row_value["row_num"] = row_num
                            if row[0] == None:
                                key_val = str(row[find_col-1]).strip()
                            else:
                                key_val = str(row[find_col-2]).strip()
                            if "_Function_" in sheet.name:
                                key_tmp = f"{key_val}[{key}]"
                            else:
                                key_tmp = f"{str(key_val.split("\n")[0]).strip()}[{key}]"
                            
                            if key_tmp in spec_dict:
                                if spec_dict[key_tmp]["Need to update CS?"] != row_value["Need to update CS?"]:
                                    spec_dict[key_tmp]["Need to update CS?"] = "Yes"
                                if spec_dict[key_tmp]["OPL"] != row_value["OPL"]:
                                    if row_value["OPL"] not in spec_dict[key_tmp]["OPL"]:
                                        spec_dict[key_tmp]["OPL"] = f"{spec_dict[key_tmp]["OPL"]},{row_value["OPL"]}"
                                if spec_dict[key_tmp]["SWE1"] != row_value["SWE1"]:
                                    spec_dict[key_tmp]["SWE1"] = "Need"
                                if spec_dict[key_tmp]["SWE2"] != row_value["SWE2"]:
                                    spec_dict[key_tmp]["SWE2"] = "Need"
                                if spec_dict[key_tmp]["SWE3"] != row_value["SWE3"]:
                                    spec_dict[key_tmp]["SWE3"] = "Need"
                                if spec_dict[key_tmp]["SWE4"] != row_value["SWE4"]:
                                    spec_dict[key_tmp]["SWE4"] = "Need"
                                if spec_dict[key_tmp]["SWE5"] != row_value["SWE5"]:
                                    spec_dict[key_tmp]["SWE5"] = "Need"
                                if spec_dict[key_tmp]["ScreenID"] != row_value["ScreenID"]:
                                    for val in str(row_value["ScreenID"]).split(","):
                                        val = str(val).strip()
                                        if val not in spec_dict[key_tmp]["ScreenID"]:
                                            spec_dict[key_tmp]["ScreenID"] = f"{spec_dict[key_tmp]["ScreenID"]},{val}"
                            else:
                                spec_dict[key_tmp] = row_value
                        row_num += 1
                else:
                    app.quit()
                    print(showwarning(title="warning", message=f"[{value}]文件sheet[{sheet.name}]中第二行未找到[Function No./Sheet Name]列"))
                    return
            key_book.close()
            print(f"close {value}")
        except Exception as e:
            app.quit()
            print(showwarning(title="warning", message=f"读取[{value}]文件失败[{e}]"))
            return
    # print(spec_dict)

    download_dict = {}
    try:
        download_book = app.books.open(download_file, update_links=False)
        cell_keyword = download_book.sheets(1).range("1:1").api.Find("Summary")
        if cell_keyword:
            find_col = cell_keyword.Column
            # 获取所有数据
            download_data = download_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in download_data:
                if row_num != 1:
                    row_value = {}
                    for index, item in enumerate(row):
                        tmp_key = str(download_data[0][index]).strip()
                        item = str(item).strip()
                        if tmp_key in row_value:
                            row_value[tmp_key] = f"{row_value[tmp_key]},{item}"
                        else:
                            row_value[tmp_key] = item
                    row_value["row_num"] = row_num
                    pattern = r'\[\w+\]\[\w+\]\[\w+\]-\[([^\]]+)\]-QNX-(\w+)$'
                    matches = re.match(pattern, str(row[find_col-1]).strip())
                    if matches:
                        tmp_value = str(matches.group(1)).strip()
                        tmp_value1 = str(matches.group(2)).strip()
                        tmp_value = tmp_value.replace("Function_","")
                        tmp_value = tmp_value.replace("(delete)","")
                        last_dot_index = tmp_value.rfind('.')
                        tmp_value = f"{tmp_value[:last_dot_index]}[{tmp_value1}]"
                        download_dict[tmp_value] = row_value
                    else:
                        error_list.append(f"第[{row_num}]行, Summary 列数据[{row[find_col-1]}]格式不正确")
                row_num += 1
            # print(download_dict)
            download_book.close()
        else:
            app.quit()
            print(showwarning(title="warning", message=f"{valdownload_fileue}文件sheet1中第一行未找到[Summary]列"))
            return
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{valdownload_fileue}]文件失败[{e}]"))
        return

    for key,values in download_dict.items():
        line = values["row_num"]
        if key in spec_dict:
            if type == 1:
                if spec_dict[key]["Need to update CS?"] == "Yes":
                    if values["Custom field (AASP Doc / CS Creation)"] != "Not":
                        error_list.append(f"第[{line}]行, Custom field (AASP Doc / CS Creation) 列数据不是[Not]")
                else:
                    if values["Custom field (AASP Doc / CS Creation)"] != "NA":
                        error_list.append(f"第[{line}]行, Custom field (AASP Doc / CS Creation) 列数据不是[NA]")

                if spec_dict[key]["OPL"] == "None" or spec_dict[key]["OPL"] == "No Need":
                    if values["Custom field (Blocker OPL Extraction)"] != "NA":
                        error_list.append(f"第[{line}]行, Custom field (Blocker OPL Extraction) 列数据不是[NA]")
                    if values["Custom field (OPL Ticket Number)"] != "None":
                        error_list.append(f"第[{line}]行, Custom field (OPL Ticket Number) 列数据不是[None]")
                else:
                    if values["Custom field (Blocker OPL Extraction)"] != "Done":
                        error_list.append(f"第[{line}]行, Custom field (Blocker OPL Extraction) 列数据不是[Done]")
                    if values["Custom field (OPL Ticket Number)"] != spec_dict[key]["OPL"]:
                        for opl in str(values["Custom field (OPL Ticket Number)"]).split("\r\n"):
                            if opl not in spec_dict[key]["OPL"]:
                                error_list.append(f"第[{line}]行, Custom field (OPL Ticket Number) 列数据[{opl}]不正确")

                if spec_dict[key]["SWE1"] != values["Custom field (SWE1 work)"]:
                    error_list.append(f"第[{line}]行, Custom field (SWE1 work) 列数据不正确")
                if spec_dict[key]["SWE2"] != values["Custom field (SWE2 work)"]:
                    error_list.append(f"第[{line}]行, Custom field (SWE2 work) 列数据不正确")
                if spec_dict[key]["SWE3"] != values["Custom field (SWE3 work)"]:
                    error_list.append(f"第[{line}]行, Custom field (SWE3 work) 列数据不正确")
                if spec_dict[key]["SWE4"] != values["Custom field (SWE4 work)"]:
                    error_list.append(f"第[{line}]行, Custom field (SWE4 work) 列数据不正确")
                if spec_dict[key]["SWE5"] != values["Custom field (SWE5 work)"]:
                    error_list.append(f"第[{line}]行, Custom field (SWE5 work) 列数据不正确")

                if spec_dict[key]["ScreenID"] != values["Custom field (Target Screen ID)"]:
                    val_list = str(values["Custom field (Target Screen ID)"]).split("\n")
                    for val in val_list:
                        val = val.replace("\r","")
                        if val not in spec_dict[key]["ScreenID"]:
                            error_list.append(f"第[{line}]行, Custom field (Target Screen ID) 列数据[{val}]不正确")

                if values["Custom field (Delta Contents Summary)"] == "None":
                    error_list.append(f"第[{line}]行, Custom field (Delta Contents Summary) 列数据是[None]")

                if values["Assignee"] == "BSBO4008243" or values["Assignee"] == "BSBO4008273":
                    if values["Custom field (SWE1 work)"] == "NO Need" and values["Custom field (SWE2 work)"] == "NO Need" and values["Custom field (SWE3 work)"] == "NO Need" and values["Custom field (SWE4 work)"] == "NO Need" and values["Custom field (SWE5 work)"] == "NO Need":
                        if values["Status"] == "Close" or values["Status"] == "Cancel":
                            error_list.append(f"第[{line}]行, Assignee 列数据不正确")
                    else:
                        if values["Status"] == "In Review" or values["Status"] == "IN PI PREPARATION":
                            error_list.append(f"第[{line}]行, Assignee 列数据不正确")
            else:
                if values["Status"] == "IN PI PREPARATION":
                    if spec_dict[key]["Need to update CS?"] == "Yes":
                        if values["Custom field (AASP Doc / CS Creation)"] != "Done":
                            error_list.append(f"第[{line}]行, Custom field (AASP Doc / CS Creation) 列数据不是[Done]")

                    if values["Custom field (HMI Story Link)"] == "None" or values["Custom field (API Story Link)"] == "None" or values["Custom field (Alignment Story Link)"] == "None":
                        error_list.append(f"第[{line}]行, Custom field (HMI Story Link)/Custom field (Alignment Story Link)/Custom field (API Story Link) 列数据是[None]")
                    else:
                        if values["Custom field (Ticket Linking between Epic and Story tickets)"] != "Done":
                            error_list.append(f"第[{line}]行, Custom field (Ticket Linking between Epic and Story tickets) 列数据不是[Done]")
        else:
            error_list.append(f"第[{line}]行, Summary 列数据[{key}]没有找到对应的specdalte数据")

    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')

    app.quit()
    print(showinfo(title="info", message=f"SpecChange票迁移检查[SUCCESS END] !!!"))


# -------------------------------------------------------------------------------------page_4-------------------------------------------------------------------------------------
# 界面参数
page_4 = ttk.Frame(right_frame)

def on_entry_pi_in_4(event):
    if PI_entry_4.get() == "eg:PI26":
        PI_entry_4.delete(0, tk.END)  # 清空内容
        PI_entry_4.config(fg="black")  # 设置文本颜色为黑色

def on_entry_pi_out_4(event):
    if PI_entry_4.get() == "":
        PI_entry_4.insert(0, "eg:PI26")  # 插入提示字符
        PI_entry_4.config(fg="grey")  # 设置文本颜色为灰色
# PI
PI_label_4 = tk.Label(page_4, width=10, text="PI")
PI_label_4.place(x=50, y=35, anchor="w")
PI_entry_4 = tk.Entry(page_4, width=10, fg="grey")
PI_entry_4.insert(0, "eg:PI26")  # 设置初始提示字符
PI_entry_4.place(x=100, y=35, anchor="w")
# 绑定事件
PI_entry_4.bind("<FocusIn>", on_entry_pi_in_4)  # 获取焦点时触发
PI_entry_4.bind("<FocusOut>", on_entry_pi_out_4)  # 失去焦点时触发
# 文件路径
def import_file_select_4():
    file_path = filedialog.askopenfilename()
    import_4.config(text=file_path)
import_4 = tk.Message(page_4, width=300, text="")
import_4.place(x=20, y=70, anchor="w")
import_botton_4 = tk.Button(page_4, text="Story file", width=10, command=import_file_select_4)
import_botton_4.place(x=350, y=50)

def epic_file_select_4():
    file_path = filedialog.askopenfilename()
    epic_4.config(text=file_path)
epic_4 = tk.Message(page_4, width=300, text="")
epic_4.place(x=20, y=120, anchor="w")
epic_botton_4 = tk.Button(page_4, text="epic csv", width=10, command=epic_file_select_4)
epic_botton_4.place(x=350, y=100)

def download_file_select_4():
    file_path = filedialog.askopenfilename()
    download_4.config(text=file_path)
download_4 = tk.Message(page_4, width=300, text="")
download_4.place(x=20, y=170, anchor="w")
download_botton_4 = tk.Button(page_4, text="SpecChange", width=10, command=download_file_select_4)
download_botton_4.place(x=350, y=150)

def start_4():
    datacheck_4(import_4["text"], epic_4["text"], download_4["text"])
status_4 = tk.Label(page_4, width=50, text="")
status_4.place(x=30, y=210, anchor="w")
start_botton_4 = tk.Button(page_4, text="开始", width=10, command=start_4)
start_botton_4.place(x=350, y=200)

def datacheck_4(Story_file, epic_file, SpecChange_file):
    status_4["text"] = "......"
    page_4.update()
    time.sleep(0.05)
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except:
        pass
        
    error_list = []
    PI_value = str(PI_entry_4.get()).strip()
    pattern = r'^PI\d+$'
    PI_match = re.match(pattern, PI_value)
    if not PI_match:
        print(showwarning(title="warning", message=f"输入PI=[{PI_value}]数据不正确"))
        return

    app = xw.App(visible=False,add_book=False)
    epic_dict = {}
    try:
        epic_book = app.books.open(epic_file, update_links=False)
        cell_keyword = epic_book.sheets(1).range("1:1").api.Find("Issue key")
        if cell_keyword:
            find_col = cell_keyword.Column - 1
            # 获取所有数据
            tmp_data = epic_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in tmp_data:
                if row_num != 1:
                    row_value = {}
                    for index, item in enumerate(row):
                        row_value[tmp_data[0][index]] = str(item).strip()
                    row_value["row_num"] = row_num
                    epic_dict[str(row[find_col]).strip()] = row_value
                row_num += 1
            # print(epic_dict)
            epic_book.close()
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{epic_file}]文件sheet1中第一行未找到[Issue key]列"))
            return
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{epic_file}]文件失败[{e}]"))
        return

    SpecChange_dict = {}
    try:
        SpecChange_book = app.books.open(SpecChange_file, update_links=False)
        cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (Feature)")
        if cell_keyword:
            find_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (Epic Link)")
            Epic_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE1 work)")
            SWE1_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE2 work)")
            SWE2_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE3 work)")
            SWE3_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE4 work)")
            SWE4_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE5 work)")
            SWE5_col = cell_keyword.Column-1
            # 获取所有数据
            tmp_data = SpecChange_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in tmp_data:
                if row_num != 1:
                    if str(row[SWE1_col]).strip() == "Need" or str(row[SWE2_col]).strip() == "Need" or str(row[SWE3_col]).strip() == "Need" or str(row[SWE4_col]).strip() == "Need" or str(row[SWE5_col]).strip() == "Need":
                        list_val = f"{str(row[Epic_col]).strip()}[{str(row[find_col]).strip()}]"
                        if list_val not in SpecChange_dict:
                            SpecChange_dict[list_val] = str(row[Epic_col]).strip()
                row_num += 1
            # print(SpecChange_dict)
            SpecChange_book.close()
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{SpecChange_file}]文件sheet1中第一行未找到[Custom field (Feature)]列"))
            return
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{SpecChange_file}]文件失败[{e}]"))
        return

    Story_dict = {}
    try:
        Story_book = app.books.open(Story_file, update_links=False)
        cell_keyword = Story_book.sheets(1).range("1:1").api.Find("Epic Link(CDCFM)")
        if cell_keyword:
            find_col = cell_keyword.Column - 1
            # 获取所有数据
            tmp_data = Story_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in tmp_data:
                if row_num != 1:
                    row_value = {}
                    for index, item in enumerate(row):
                        tmp_key = str(tmp_data[0][index]).strip()
                        item = str(item).strip()
                        if tmp_key in row_value:
                            row_value[tmp_key] = f"{row_value[tmp_key]},{item}"
                        else:
                            row_value[tmp_key] = item
                    row_value["row_num"] = row_num
                    tmp_key = str(row[find_col]).strip()
                    if "AD" in row_value["Labels"]:
                        dict_val = f"{tmp_key}[AD]"
                    elif "Ordinary" in row_value["Labels"]:
                        dict_val = f"{tmp_key}[Ordinary]"
                    elif "Popup" in row_value["Labels"]:
                        dict_val = f"{tmp_key}[Popup]"
                    else:
                        error_list.append(f"文件[{Story_file}]中第[{row_num}]行数据[Labels]数据{row_value["Labels"]}不正确")
                    Story_dict[dict_val] = row_value
                row_num += 1
            # print(Story_dict)
            Story_book.close()
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{Story_file}]文件sheet1中第一行未找到[Epic Link(CDCFM)]列"))
            return
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{Story_file}]文件失败[{e}]"))
        return

    for key,value in Story_dict.items():
        if SpecChange_dict.get(key) == None:
            error_list.append(f"文件[{Story_file}]中数据[{key}]未在文件[{SpecChange_file}]中找到有效数据")

    for key,value in SpecChange_dict.items():
        if Story_dict.get(key):
            dict_value = Story_dict[key]
            line = dict_value["row_num"]
            if dict_value["Description"] != "None":
                error_list.append(f"第[{line}]行, Description 列数据不是[None]")
            if dict_value["Issue Type"] != "Story":
                error_list.append(f"第[{line}]行, Issue Type 列数据不是[Story]")
            if dict_value["Priority"] != "D":
                error_list.append(f"第[{line}]行, Priority 列数据不是[D]")
            if dict_value["Function Domain"] != "18_Cluster":
                error_list.append(f"第[{line}]行, Function Domain 列数据不是[18_Cluster]")
            if PI_value not in dict_value["Labels"]:
                error_list.append(f"第[{line}]行, Labels 数据缺少[{PI_value}]")
            Summary = f"{epic_dict[value]["Summary"]}(HMI-QNX)"
            count = 0
            for skey in Story_dict:
                if value in skey:
                    count += 1
            if count > 1:
                if "AD dedicated_Multi Lane" not in Summary and "AD dedicated_Telltale" not in Summary:
                    error_list.append(f"第[{line}]行, Summary 列数据[{Summary}]检查到多条数据情况")
                Summary = f"{Summary}-{key.replace(value,"").strip("[]")}"
            if dict_value["Summary"] != Summary:
                error_list.append(f"第[{line}]行, Summary 列数据[{dict_value["Summary"]}]不正确,应该是[{Summary}]")
        else:
            error_list.append(f"文件[{SpecChange_file}]中数据[{key}]未在文件[{Story_file}]中找到有效数据")

    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')

    app.quit()
    print(showinfo(title="info", message=f"HMI story检查[SUCCESS END] !!!"))

# -------------------------------------------------------------------------------------page_5-------------------------------------------------------------------------------------
# 界面参数
page_5 = ttk.Frame(right_frame)

def on_entry_pi_in_4(event):
    if PI_entry_5.get() == "eg:PI26":
        PI_entry_5.delete(0, tk.END)  # 清空内容
        PI_entry_5.config(fg="black")  # 设置文本颜色为黑色

def on_entry_pi_out_4(event):
    if PI_entry_5.get() == "":
        PI_entry_5.insert(0, "eg:PI26")  # 插入提示字符
        PI_entry_5.config(fg="grey")  # 设置文本颜色为灰色
# PI
PI_label_5 = tk.Label(page_5, width=10, text="PI")
PI_label_5.place(x=50, y=35, anchor="w")
PI_entry_5 = tk.Entry(page_5, width=10, fg="grey")
PI_entry_5.insert(0, "eg:PI26")  # 设置初始提示字符
PI_entry_5.place(x=100, y=35, anchor="w")
# 绑定事件
PI_entry_5.bind("<FocusIn>", on_entry_pi_in_4)  # 获取焦点时触发
PI_entry_5.bind("<FocusOut>", on_entry_pi_out_4)  # 失去焦点时触发
# 文件路径
def download_file_select_5():
    file_path = filedialog.askopenfilename()
    download_5.config(text=file_path)
download_5 = tk.Message(page_5, width=300, text="")
download_5.place(x=20, y=70, anchor="w")
download_botton_5 = tk.Button(page_5, text="Alignment", width=10, command=download_file_select_5)
download_botton_5.place(x=350, y=50)

def SpecChange_file_select_5():
    file_path = filedialog.askopenfilename()
    SpecChange_5.config(text=file_path)
SpecChange_5 = tk.Message(page_5, width=300, text="")
SpecChange_5.place(x=20, y=120, anchor="w")
SpecChange_botton_5 = tk.Button(page_5, text="SpecChange", width=10, command=SpecChange_file_select_5)
SpecChange_botton_5.place(x=350, y=100)


def start_5():
    datacheck_5(download_5["text"], SpecChange_5["text"])
status_5 = tk.Label(page_5, width=50, text="")
status_5.place(x=30, y=170, anchor="w")
start_botton_5 = tk.Button(page_5, text="开始", width=10, command=start_5)
start_botton_5.place(x=350, y=155)


def datacheck_5(Story_file, SpecChange_file):
    status_5["text"] = "......"
    page_5.update()
    time.sleep(0.05)
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except:
        pass
        
    error_list = []
    PI_value = str(PI_entry_5.get()).strip()
    pattern = r'^PI\d+$'
    PI_match = re.match(pattern, PI_value)
    if not PI_match:
        print(showwarning(title="warning", message=f"输入PI=[{PI_value}]数据不正确"))
        return

    app = xw.App(visible=False,add_book=False)
    SpecChange_dict = {}
    try:
        SpecChange_book = app.books.open(SpecChange_file, update_links=False)
        cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (Feature)")
        if cell_keyword:
            find_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (Epic Link)")
            Epic_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE1 work)")
            SWE1_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE2 work)")
            SWE2_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE3 work)")
            SWE3_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE4 work)")
            SWE4_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (SWE5 work)")
            SWE5_col = cell_keyword.Column-1
            cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find("Custom field (AASP Doc / CS Creation)")
            AASP_col = cell_keyword.Column-1
            # 获取所有数据
            tmp_data = SpecChange_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in tmp_data:
                if row_num != 1:
                    if str(row[SWE1_col]).strip() == "Need" or str(row[SWE2_col]).strip() == "Need" or str(row[SWE3_col]).strip() == "Need" or str(row[SWE4_col]).strip() == "Need" or str(row[SWE5_col]).strip() == "Need":
                        if str(row[AASP_col]).strip() == "Not" or str(row[AASP_col]).strip() == "Done":
                            spec_key = str(row[Epic_col]).strip()
                            spec_val = str(row[find_col]).strip()
                            if spec_key in SpecChange_dict:
                                SpecChange_dict[spec_key] = f"{SpecChange_dict[spec_key]},{spec_val}"
                            else:
                                SpecChange_dict[spec_key] = spec_val
                row_num += 1
            # print(SpecChange_dict)
            SpecChange_book.close()
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{SpecChange_file}]文件sheet1中第一行未找到[Custom field (Feature)]列"))
            return
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{SpecChange_file}]文件失败[{e}]"))
        return
    
    Story_dict = {}
    try:
        Story_book = app.books.open(Story_file, update_links=False)
        cell_keyword = Story_book.sheets(1).range("1:1").api.Find("Epic Link(CDCFM)")
        if cell_keyword:
            find_col = cell_keyword.Column-1
            # 获取所有数据
            tmp_data = Story_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in tmp_data:
                if row_num != 1:
                    row_value = {}
                    for index, item in enumerate(row):
                        tmp_key = str(tmp_data[0][index]).strip()
                        item = str(item).strip()
                        if tmp_key in row_value:
                            row_value[tmp_key] = f"{row_value[tmp_key]},{item}"
                        else:
                            row_value[tmp_key] = item
                    row_value["row_num"] = row_num
                    Story_dict[str(row[find_col]).strip()] = row_value
                row_num += 1
            # print(Story_dict)
            Story_book.close()
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{Story_file}]文件sheet1中第一行未找到[Epic Link(CDCFM)]列"))
            return
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{Story_file}]文件失败[{e}]"))
        return

    for key,values in Story_dict.items():
        if SpecChange_dict.get(key):
            line = values["row_num"]
            pattern = rf"\[Cluster\]\[{PI_value}\] QNX OS - CGIApplication I/F Alignment - (\w+)$"
            matches = re.match(pattern, values["Summary"])
            if matches:
                tmp_value = str(matches.group(1)).strip()
                if tmp_value not in SpecChange_dict[key]:
                    error_list.append(f"文件[{Story_file}]中数据[{key}:{tmp_value}]未在文件[{SpecChange_file}]中找到有效数据")
            else:
                error_list.append(f"第[{line}]行, Summary 列数据[{values["Summary"]}]格式不正确")
            if values["Issue Type"] != "Story":
                error_list.append(f"第[{line}]行, Issue Type 列数据不是[Story]")
            if values["Supplier"] != "MARELLI":
                error_list.append(f"第[{line}]行, Supplier  列数据不是[MARELLI]")
            if values["Function Domain"] != "18_Cluster":
                error_list.append(f"第[{line}]行, Function Domain 列数据不是[18_Cluster]")
            if values["Vehicle Project/s"] != "Global":
                error_list.append(f"第[{line}]行, Vehicle Project/s 列数据不是[Global]")

            if "API_ALIGNMENT" not in values["Labels"]:
                error_list.append(f"第[{line}]行, Labels 列数据缺少[API_ALIGNMENT]")
            if f"API_{PI_value}" not in values["Labels"]:
                error_list.append(f"第[{line}]行, Labels 列数据缺少[API_{PI_value}]")
            if "CGI_API" not in values["Labels"]:
                error_list.append(f"第[{line}]行, Labels 列数据缺少[CGI_API]")
            if "Cluster" not in values["Labels"]:
                error_list.append(f"第[{line}]行, Labels 列数据缺少[Cluster]")
        else:
            error_list.append(f"文件[{Story_file}]中数据[{key}]未在文件[{SpecChange_file}]中找到有效数据")

    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')
    
    app.quit()
    print(showinfo(title="info", message=f"Alignment story检查[SUCCESS END] !!!"))

# -------------------------------------------------------------------------------------page_6-------------------------------------------------------------------------------------
# 界面参数
page_6 = ttk.Frame(right_frame)

def on_entry_pi_in_6(event):
    if PI_entry_6.get() == "eg:26":
        PI_entry_6.delete(0, tk.END)  # 清空内容
        PI_entry_6.config(fg="black")  # 设置文本颜色为黑色

def on_entry_pi_out_6(event):
    if PI_entry_6.get() == "":
        PI_entry_6.insert(0, "eg:26")  # 插入提示字符
        PI_entry_6.config(fg="grey")  # 设置文本颜色为灰色
# PI
PI_label_6 = tk.Label(page_6, width=10, text="PI")
PI_label_6.place(x=50, y=35, anchor="w")
PI_entry_6 = tk.Entry(page_6, width=10, fg="grey")
PI_entry_6.insert(0, "eg:26")  # 设置初始提示字符
PI_entry_6.place(x=100, y=35, anchor="w")
# 绑定事件
PI_entry_6.bind("<FocusIn>", on_entry_pi_in_6)  # 获取焦点时触发
PI_entry_6.bind("<FocusOut>", on_entry_pi_out_6)  # 失去焦点时触发
# 文件路径
def download_file_select_6():
    file_path = filedialog.askopenfilename()
    download_6.config(text=file_path)
download_6 = tk.Message(page_6, width=300, text="")
download_6.place(x=20, y=70, anchor="w")
download_botton_6 = tk.Button(page_6, text="Story_file", width=10, command=download_file_select_6)
download_botton_6.place(x=350, y=50)

def SpecChange_file_select_6():
    file_path = filedialog.askopenfilename()
    SpecChange_6.config(text=file_path)
SpecChange_6 = tk.Message(page_6, width=300, text="")
SpecChange_6.place(x=20, y=120, anchor="w")
SpecChange_botton_6 = tk.Button(page_6, text="download_file", width=10, command=SpecChange_file_select_6)
SpecChange_botton_6.place(x=350, y=100)


def start_6(type):
    datacheck_6(download_6["text"], SpecChange_6["text"], type)
status_6 = tk.Label(page_6, width=50, text="")
status_6.place(x=30, y=170, anchor="w")
start_botton_6 = tk.Button(page_6, text="HMI检查", width=10, command=lambda: start_6(1))
start_botton_6.place(x=100, y=200)
start_botton_6 = tk.Button(page_6, text="Alignment检查", width=10, command=lambda: start_6(2))
start_botton_6.place(x=200, y=200)


def datacheck_6(Story_file, SpecChange_file, type):
    status_6["text"] = "......"
    page_6.update()
    time.sleep(0.05)
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except:
        pass
    PI_value = str(PI_entry_6.get()).strip()
    if not PI_value.isnumeric():
        print(showwarning(title="warning", message=f"输入PI=[{PI_value}]数据不是纯数字"))
        return

    app = xw.App(visible=False,add_book=False)
    if type == 1:
        tital_dict = {
            'Issue Type':'Issue Type',
            'Summary':'Summary',
            'Priority':'Priority',
            'Epic Link(CDCFM)':'Custom field (Epic Link)',
            'Function Domain':'Custom field (Function Domain)',
            'Assignee':'Assignee',
            'Reporter':'Reporter'
            }
    else:
        tital_dict = {
            'Issue Type':'Issue Type',
            'Summary':'Summary',
            'Supplier':'Custom field (Product Owner)',
            'Epic Link(CDCFM)':'Custom field (Epic Link)',
            'Function Domain':'Custom field (Function Domain)',
            'Vehicle Project/s':'Custom field (Spec version to be Revised)',
            'Assignee':'Assignee',
            'Reporter':'Reporter'
            }
    error_list = []
    Story_dict = {}
    try:
        Story_book = app.books.open(Story_file, update_links=False)
        cell_keyword = Story_book.sheets(1).range("1:1").api.Find(What="Summary", LookAt=1)
        if cell_keyword:
            find_col = cell_keyword.Column - 1
            # 获取所有数据
            tmp_data = Story_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in tmp_data:
                if row_num != 1:
                    row_value = {}
                    for index, item in enumerate(row):
                        tmp_key = str(tmp_data[0][index]).strip()
                        item = str(item).strip()
                        if tmp_key in row_value:
                            row_value[tmp_key] = f"{row_value[tmp_key]},{item}"
                        else:
                            row_value[tmp_key] = item
                    row_value["row_num"] = row_num
                    Story_dict[str(row[find_col]).strip()] = row_value
                row_num += 1
            # print(Story_dict)
            Story_book.close()
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{Story_file}]文件sheet1中第一行未找到[Summary]列"))
            return
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{Story_file}]文件失败[{e}]"))
        return

    SpecChange_dict = {}
    try:
        SpecChange_book = app.books.open(SpecChange_file, update_links=False)
        cell_keyword = SpecChange_book.sheets(1).range("1:1").api.Find(What="Summary", LookAt=1)
        if cell_keyword:
            find_col = cell_keyword.Column - 1
            # 获取所有数据
            tmp_data = SpecChange_book.sheets(1).used_range.value
            # 打印数据
            row_num = 1
            for row in tmp_data:
                if row_num != 1:
                    row_value = {}
                    for index, item in enumerate(row):
                        tmp_key = str(tmp_data[0][index]).strip()
                        item = str(item).strip()
                        if tmp_key in row_value:
                            row_value[tmp_key] = f"{row_value[tmp_key]},{item}"
                        else:
                            row_value[tmp_key] = item
                    row_value["row_num"] = row_num
                    SpecChange_dict[str(row[find_col]).strip()] = row_value
                row_num += 1
            # print(SpecChange_dict)
            SpecChange_book.close()
        else:
            app.quit()
            print(showwarning(title="warning", message=f"[{SpecChange_file}]文件sheet1中第一行未找到[Summary)]列"))
            return
    except Exception as e:
        app.quit()
        print(showwarning(title="warning", message=f"读取[{SpecChange_file}]文件失败[{e}]"))
        return

    for key,values in Story_dict.items():
        if key in SpecChange_dict:
            for tkey,tvalue in tital_dict.items():
                if values[tkey] != SpecChange_dict[key][tvalue] and values[tkey] not in SpecChange_dict[key][tvalue]:
                    error_list.append(f"文件[{Story_file}]中[{values["row_num"]}]行数据[{tkey}:{values[tkey]}]与文件[{SpecChange_file}]中[{SpecChange_dict[key]["row_num"]}]行数据[{tvalue}:{SpecChange_dict[key][tvalue]}]不一致")
            label_spec = SpecChange_dict[key]["Custom field (Labels)"]
            label_list = values["Labels"].split(",")
            for lable in label_list:
                if lable not in label_spec:
                    error_list.append(f"文件[{Story_file}]中[{values["row_num"]}]行[Labels]列数据[{lable}]与文件[{SpecChange_file}]中[{SpecChange_dict[key]["row_num"]}]行[Labels:{label_spec}]数据不一致")
            
            if SpecChange_dict[key]["Assignee"] == "BSBO4008243" or SpecChange_dict[key]["Assignee"] == "BSBO4008273":
                error_list.append(f"文件[{SpecChange_file}]中第[{SpecChange_dict[key]["row_num"]}]行[Assignee]列数据是[BSBO4008243/BSBO4008273]")
                
            if type == 1:
                if SpecChange_dict[key]["Custom field (Product Owner)"] != "NISSAN":
                    error_list.append(f"文件[{SpecChange_file}]中第[{SpecChange_dict[key]["row_num"]}]行[Custom field (Product Owner)]列数据不是[NISSAN]")
                plan = f"IRI{PI_value}.03.01"
                if SpecChange_dict[key]["Custom field (Design Done(Plan))"] != plan:
                    error_list.append(f"文件[{SpecChange_file}]中第[{SpecChange_dict[key]["row_num"]}]行[Custom field (Design Done(Plan))]列数据不是[{plan}]")
                plan = f"IRI{PI_value}.03.02"
                if SpecChange_dict[key]["Custom field (Implementation Done(Plan))"] != plan:
                    error_list.append(f"文件[{SpecChange_file}]中第[{SpecChange_dict[key]["row_num"]}]行[Custom field (Implementation Done(Plan))]列数据不是[{plan}]")
                plan = f"IRI{PI_value}.03.03"
                if SpecChange_dict[key]["Custom field (Verification Done(Plan))"] != plan:
                    error_list.append(f"文件[{SpecChange_file}]中第[{SpecChange_dict[key]["row_num"]}]行[Custom field (Verification Done(Plan))]列数据不是[{plan}]")
        else:
            error_list.append(f"文件[{Story_file}]中数据[{key}]未在文件[{SpecChange_file}]中找到有效数据")

    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')

    app.quit()
    print(showinfo(title="info", message=f"story与csv一致性检查[SUCCESS END] !!!"))

# -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 添加一些内容到页面
ttk.Label(page_1, text="SpecChange起票前csv检查").pack(pady=5)
ttk.Label(page_2, text="SpecChange期票后票的检查").pack(pady=5)
ttk.Label(page_3, text="SpecChange票迁移检查").pack(pady=5)
ttk.Label(page_4, text="HMI story检查").pack(pady=5)
ttk.Label(page_5, text="Alignment story检查").pack(pady=5)
ttk.Label(page_6, text="story与csv一致性检查").pack(pady=5)
# 在左侧 Frame 中添加按钮,用于切换页面
def show_page(page):
    for p in [page_1, page_2, page_3, page_4, page_5, page_6]:
        p.pack_forget()  # 隐藏所有页面
    page.pack(fill=tk.BOTH, expand=True)  # 显示当前页面

button_1 = ttk.Button(left_frame, text="SpecChange起票前csv检查", command=lambda: show_page(page_1))
button_1.pack(pady=10, fill=tk.X)
button_2 = ttk.Button(left_frame, text="SpecChange期票后票的检查", command=lambda: show_page(page_2))
button_2.pack(pady=10, fill=tk.X)
button_3 = ttk.Button(left_frame, text="SpecChange票迁移检查", command=lambda: show_page(page_3))
button_3.pack(pady=10, fill=tk.X)
button_4 = ttk.Button(left_frame, text="HMI story检查", command=lambda: show_page(page_4))
button_4.pack(pady=10, fill=tk.X)
button_5 = ttk.Button(left_frame, text="Alignment story检查", command=lambda: show_page(page_5))
button_5.pack(pady=10, fill=tk.X)
button_6 = ttk.Button(left_frame, text="story与csv一致性检查", command=lambda: show_page(page_6))
button_6.pack(pady=10, fill=tk.X)

# 默认显示第一个页面
show_page(page_1)
# # 将Notebook放入根窗口
# notebook.pack(expand=1, fill="both")

# 回调函数
def refresh():
    window.after(100, refresh)

# 注册第一次回调函数
window.after(100, refresh)

window.mainloop()